from math import tan, floor

from kivy.event import EventDispatcher
from kivy.graphics.vertex_instructions import Ellipse, Rectangle, Triangle
from kivy.metrics import inch, dp

from dryfire.model.spaceModel import OutdoorSpaceModel, DryFireSpaceModel

from kivy.properties import NumericProperty, BooleanProperty, DictProperty, \
        BoundedNumericProperty, ReferenceListProperty, VariableListProperty


class OutdoorShapeModel(OutdoorSpaceModel):
    """
    This is a shape in an outdoor target.
    The shape is a circle or a rectangle.
    The shape has a height and width in inches.
    The target has a distance in yards.
    """

    shape_circle = 1
    shape_rectangle = 2
    shape_quad = 3
    shapes = [shape_circle, shape_rectangle, shape_quad]

    def __init__(self, top_width_inches, bottom_width_inches, height_inches, shape, distance_yards, description):
        """
        type: height_inches: float, int
        type: width_inches: float, int
        type: shape: OutdoorShapeModel.shapes
        type: distance_yards: float, int
        type: description: str
        """
        OutdoorSpaceModel.__init__(self, top_width_inches, bottom_width_inches, height_inches, distance_yards, description)
        self.shape = shape


class DryFireShapeModel(DryFireSpaceModel):
    """
    This is a shape on an indoor target.
    It has a corresponding OutdoorShapeModel object.
    The indoor target has a distance in feet.
    The shape has a graphic which is a kivy.graphics Circle or Rectangle.
    """
    def __init__(self, outdoor_shape_model, distance_feet):
        """
        type: outdoor_shape_model: OutdoorShapeModel
        type: distance_feet: float, int
        """
        DryFireSpaceModel.__init__(self, outdoor_shape_model, distance_feet)

    # properties

    def get_graphic(self, pos_x, pos_y):
        size = (self.width_pixels, self.height_pixels)
        if self._outdoor_space_model.shape == OutdoorShapeModel.shape_circle:
            return (Ellipse(size=size, pos=(pos_x, pos_y)),)
        elif self._outdoor_space_model.shape == OutdoorShapeModel.shape_rectangle:
            return (Rectangle(size=size, pos=(pos_x, pos_y)),)
        elif self._outdoor_space_model.shape == OutdoorShapeModel.shape_quad:
            if self.top_width_inches > self.bottom_width_inches:
                # top is wider than the bottom
                # calc widths
                rectangle_width_inches = self.bottom_width_inches
                rectangle_width_pixels = floor((rectangle_width_inches / self.top_width_inches) * self.width_pixels)
                triangles_width_pixels = self.width_pixels - rectangle_width_pixels
                triangle1_width_pixels = floor(triangles_width_pixels / 2)
                triangle2_width_pixels = triangles_width_pixels - triangle1_width_pixels
                # left triangle
                # top left
                x1 = pos_x
                y1 = pos_y + self.height_pixels
                # top right
                x2 = x1 + triangle1_width_pixels
                y2 = y1
                # bottom right
                x3 = x2
                y3 = pos_y 
                t1 = Triangle(points=(x1, y1, x2, y2, x3, y3))
                # rectangle
                r = Rectangle(
                        # pos=(x3 + 1, pos_y),
                        pos=(x3, pos_y),
                        size=(rectangle_width_pixels, self.height_pixels))
                # right triangle
                # top left
                x1 = x3 + rectangle_width_pixels
                # y1 = y1
                # top right
                x2 = x1 + triangle2_width_pixels
                y2 = y1
                # bottom left
                x3 = x3 + rectangle_width_pixels 
                # y3 = y3
                t2 = Triangle(points=(x1, y1, x2, y2, x3, y3))
            else:
                # bottom is wider than the top
                # calc widths
                rectangle_width_inches = self.top_width_inches
                rectangle_width_pixels = floor((rectangle_width_inches / self.bottom_width_inches) * self.width_pixels)
                triangles_width_pixels = self.width_pixels - rectangle_width_pixels
                triangle1_width_pixels = floor(triangles_width_pixels / 2)
                triangle2_width_pixels = triangles_width_pixels - triangle1_width_pixels 
                # left triangle
                # bottom left
                x1 = pos_x
                y1 = pos_y
                # bottom right
                x2 = x1 + triangle1_width_pixels
                y2 = y1
                # top right
                x3 = x2
                y3 = y2 + self.height_pixels 
                t1 = Triangle(points=(x1, y1, x2, y2, x3, y3))
                # rectangle
                r = Rectangle(
                        pos=(x3, pos_y),
                        size=(rectangle_width_pixels, self.height_pixels))
                # right triangle
                # bottom left
                x1 = x3 + rectangle_width_pixels
                # y1 = y1
                # top left
                x2 = x1
                y2 = y1 + self.height_pixels
                # bottom right
                x3 = x1 + triangle2_width_pixels
                y3 = y1
                t2 = Triangle(points=(x1, y1, x2, y2, x3, y3))
            return (t1, r, t2)
